package com.zycfc.zsf.boot.mybatis.generator.codegen.main;

import com.zycfc.zsf.boot.mybatis.generator.codegen.exception.*;
import org.dom4j.io.*;
import org.dom4j.*;
import com.zycfc.zsf.boot.mybatis.generator.codegen.db.*;
import com.zycfc.zsf.boot.mybatis.generator.codegen.model.*;
import java.util.*;
import freemarker.template.*;
import com.zycfc.zsf.boot.mybatis.generator.codegen.util.*;
import java.net.*;
import java.io.*;
import org.slf4j.*;

public class Codegen
{
    private static final Logger log;
    private static String rootPath;
    
    public static void setRootPath(final String path) {
        Codegen.rootPath = path;
    }
    
    private static String getRootPath() {
        if (Codegen.rootPath.isEmpty()) {
            Codegen.rootPath = new File("").getAbsolutePath();
        }
        if (!Codegen.rootPath.endsWith("/")) {
            Codegen.rootPath += "/";
        }
        return Codegen.rootPath;
    }
    
    private static String getXmlPath() throws CodegenException {
        final String configXml = getRootPath() + "codegenconfig.xml";
        final File file = new File(configXml);
        if (!file.exists()) {
            throw new CodegenException("\u8bf7\u786e\u8ba4\u914d\u7f6e\u6587\u4ef6\uff1a" + configXml + "\u662f\u5426\u5b58\u5728!");
        }
        return configXml;
    }
    
    private static String getXsdPath() throws CodegenException {
        final String path = getRootPath() + "codegen.xsd";
        final File file = new File(path);
        if (!file.exists()) {
            throw new CodegenException("schema\u6587\u4ef6" + path + "\u4e0d\u5b58\u5728");
        }
        return path;
    }
    
    private static String getPropertiesPath() throws CodegenException {
        final String path = getRootPath() + "codegen.properties";
        final File file = new File(path);
        if (!file.exists()) {
            throw new CodegenException("\u4ee3\u7801\u751f\u6210\u914d\u7f6e\u6587\u4ef6" + path + "\u4e0d\u5b58\u5728");
        }
        return path;
    }
    
    public ConfigModel loadXml(final String style, final String baseDir) throws Exception {
        final ConfigModel cm = new ConfigModel();
        final SAXReader saxReader = new SAXReader();
        Document document = null;
        try {
            final InputStream is = this.getClass().getResourceAsStream("/" + style + "/codegenconfig.xml");
            document = saxReader.read(is);
        }
        catch (DocumentException e) {
            Codegen.log.error("\u8bfb\u53d6XML\u51fa\u9519!", (Throwable)e);
            throw new CodegenException("\u8bfb\u53d6XML\u51fa\u9519!", (Throwable)e);
        }
        final Element root = document.getRootElement();
        final Element templatesEl = root.element("templates");
        final String basepath = getRootPath() + "template";
        final ConfigModel.Templates templates = cm.new Templates(basepath);
        cm.setTemplates(templates);
        final Iterator j = templatesEl.elementIterator("template");
        while (j.hasNext()) {
            final Element templateEl = j.next();
            final String id = templateEl.attributeValue("id");
            final String path = templateEl.attributeValue("path");
            templates.getTemplate().put(id, path);
        }
        final Element filesEl = root.element("files");
        if (filesEl != null) {
            final ConfigModel.Files files = cm.new Files();
            cm.setFiles(files);
            files.setBaseDir(baseDir);
            final Iterator i = filesEl.elementIterator("file");
            while (i.hasNext()) {
                final Element fileEl = i.next();
                final String refTemplate = fileEl.attributeValue("refTemplate");
                final String filename = fileEl.attributeValue("filename");
                final String dir = fileEl.attributeValue("dir");
                final String template = templates.getTemplate().get(refTemplate);
                if (template == null) {
                    throw new CodegenException("\u6ca1\u6709\u627e\u5230" + refTemplate + "\u5bf9\u5e94\u7684\u6a21\u677f!");
                }
                final String sub = fileEl.attributeValue("sub");
                final String override = fileEl.attributeValue("override");
                boolean isOverride = false;
                if (StringUtil.isNotEmpty(override) && override.equals("true")) {
                    isOverride = true;
                }
                final String append = fileEl.attributeValue("append");
                if (append != null && append.toLowerCase().equals("true")) {
                    String insertTag = fileEl.attributeValue("insertTag");
                    String startTag = fileEl.attributeValue("startTag");
                    String endTag = fileEl.attributeValue("endTag");
                    if (insertTag == null) {
                        insertTag = "<!--insertbefore-->";
                    }
                    if (StringUtil.isEmpty(startTag)) {
                        startTag = "";
                    }
                    if (StringUtil.isEmpty(endTag)) {
                        endTag = "";
                    }
                    if (sub != null && sub.toLowerCase().equals("true")) {
                        files.addFile(template, filename, dir, true, isOverride, true, insertTag, startTag, endTag);
                    }
                    else {
                        files.addFile(template, filename, dir, false, isOverride, true, insertTag, startTag, endTag);
                    }
                }
                else if (sub != null && sub.toLowerCase().equals("true")) {
                    files.addFile(template, filename, dir, true, isOverride, false, "", "", "");
                }
                else {
                    files.addFile(template, filename, dir, false, isOverride, false, "", "", "");
                }
            }
        }
        final Iterator k = root.elementIterator("genAll");
        while (k.hasNext()) {
            final Element tableEl = k.next();
            final String tableNames = tableEl.attributeValue("tableNames");
            final ConfigModel.GenAll genAll = cm.new GenAll(tableNames);
            cm.setGenAll(genAll);
            final Iterator l = tableEl.elementIterator("file");
            while (l.hasNext()) {
                final Element fileEl2 = l.next();
                final String refTemplate2 = fileEl2.attributeValue("refTemplate");
                final String filename2 = fileEl2.attributeValue("filename");
                final String extName = fileEl2.attributeValue("extName");
                final String dir2 = fileEl2.attributeValue("dir");
                final String genMode = fileEl2.attributeValue("genMode");
                final String template2 = cm.getTemplates().getTemplate().get(refTemplate2);
                if (template2 == null) {
                    throw new CodegenException("\u627e\u4e0d\u5230\u6a21\u677f\uff1a " + refTemplate2 + "!");
                }
                if ("SingleFile".equals(genMode) && filename2 == null) {
                    throw new CodegenException("\u5f53SingleFile\u6a21\u5f0f\u65f6\uff0c\u5fc5\u987b\u8981\u586bfilename!");
                }
                if ("MultiFile".equals(genMode) && extName == null) {
                    throw new CodegenException("\u5f53MultiFile\u6a21\u5f0f\u65f6\uff0c\u5fc5\u987b\u8981\u586bextName!");
                }
                final ConfigModel.GenAll.File file = genAll.new File(template2, filename2, extName, dir2, genMode);
                genAll.getFile().add(file);
                final Iterator m = fileEl2.elementIterator("variable");
                while (m.hasNext()) {
                    final Element variableEl = m.next();
                    final String name = variableEl.attributeValue("name");
                    final String value = variableEl.attributeValue("value");
                    file.getVariable().put(name, value);
                }
            }
        }
        return cm;
    }
    
    private List<TableModel> getTableModelList(final IDbHelper dbHelper, final ConfigModel configModel) throws CodegenException {
        final List<ConfigModel.Table> tables = configModel.getTables();
        final List<TableModel> tableModels = new ArrayList<TableModel>();
        for (final ConfigModel.Table table : tables) {
            final String tbName = table.getTableName();
            final TableModel tableModel = dbHelper.getByTable(tbName);
            if (tableModel == null || tableModel.getColumnList() == null || tableModel.getColumnList().size() <= 0) {
                Codegen.log.error("^^^^^^^^^\u8868\u3010" + tbName + "\u3011\u4e0d\u5b58\u5728\u8bf7\u786e\u8ba4\uff01\uff01\uff01^^^^^^^^");
            }
            else {
                tableModel.setVariables(table.getVariable());
                tableModel.setSub(false);
                tableModel.setTableName(tbName.toLowerCase());
                tableModels.add(tableModel);
            }
        }
        return tableModels;
    }
    
    private void genTableByConfig(final IDbHelper dbHelper, final ConfigModel configModel, final Configuration cfg) throws CodegenException {
        try {
            final List<TableModel> tableModels = this.getTableModelList(dbHelper, configModel);
            if (tableModels == null || tableModels.size() == 0) {
                Codegen.log.info("\u6ca1\u6709\u6307\u5b9a\u751f\u6210\u7684\u8868!");
                return;
            }
            final ConfigModel.Files files = configModel.getFiles();
            final String baseDir = files.getBaseDir();
            final List<ConfigModel.Files.File> fileList = files.getFiles();
            if (fileList == null || fileList.size() == 0) {
                Codegen.log.info("\u6ca1\u6709\u6307\u5b9a\u751f\u6210\u7684\u6587\u4ef6!");
                return;
            }
            Codegen.log.info("*********\u5f00\u59cb\u751f\u6210**********");
            for (final TableModel tableModel : tableModels) {
                final String tbName = tableModel.getTableName();
                final Map<String, String> variables = tableModel.getVariables();
                final boolean isSub = tableModel.getSub();
                for (final ConfigModel.Files.File file : fileList) {
                    String filename = file.getFilename();
                    String startTag = file.getStartTag();
                    String endTag = file.getEndTag();
                    final boolean sub = file.isSub();
                    final boolean override = file.isOverride();
                    if (isSub && !sub) {
                        continue;
                    }
                    startTag = StringUtil.replaceVariable(startTag, tbName);
                    endTag = StringUtil.replaceVariable(endTag, tbName);
                    String dir = file.getDir();
                    variables.put("class", StringUtil.tableUnderLineToHump(tableModel.getTableName()));
                    filename = StringUtil.replaceVariable(filename, variables);
                    dir = StringUtil.replaceVariable(dir, variables);
                    dir = StringUtil.combilePath(baseDir, dir);
                    final Map<String, Object> map = new HashMap<String, Object>();
                    map.put("model", tableModel);
                    map.put("vars", configModel.getVariables());
                    map.put("date", new Date());
                    if (file.getAppend()) {
                        this.appendFile(dir, filename, file.getTemplate(), configModel.getCharset(), cfg, map, file.getInsertTag(), startTag, endTag);
                    }
                    else if (override) {
                        this.genFile(dir, filename, file.getTemplate(), configModel.getCharset(), cfg, map);
                    }
                    else {
                        final File f = new File(dir + "\\" + filename);
                        if (!f.exists()) {
                            this.genFile(dir, filename, file.getTemplate(), configModel.getCharset(), cfg, map);
                            Codegen.log.info(dir + "\u8def\u5f84\u4e0b\uff1a" + filename + " \u751f\u6210\u6210\u529f!");
                        }
                        else {
                            Codegen.log.info(dir + "\u8def\u5f84\u4e0b\uff1a" + filename + " \u5df2\u5b58\u5728\uff0c\u505c\u6b62\u751f\u6210!");
                        }
                    }
                }
            }
            Codegen.log.info("*********\u6240\u6709\u6587\u4ef6\u751f\u6210\u6210\u529f!**********");
        }
        catch (IOException e) {
            throw new CodegenException(e);
        }
        catch (TemplateException e2) {
            throw new CodegenException("freemarker\u6267\u884c\u51fa\u9519!", (Throwable)e2);
        }
    }
    
    private void getAllTable(final IDbHelper dbHelper, final ConfigModel configModel, final Configuration cfg) throws CodegenException, IOException, TemplateException {
        final ConfigModel.GenAll genAll = configModel.getGenAll();
        if (genAll == null) {
            return;
        }
        List<String> tableNames = null;
        if (genAll.getTableNames() == null) {
            tableNames = dbHelper.getAllTable();
        }
        else {
            tableNames = new ArrayList<String>();
            for (final String name : genAll.getTableNames().replaceAll(" ", "").split(",")) {
                if (name.length() > 0) {
                    tableNames.add(name);
                }
            }
        }
        final int size = genAll.getFile().size();
        if (size == 0) {
            return;
        }
        Codegen.log.info("----------------\u751f\u6210\u591a\u8868\u5f00\u59cb------------------");
        for (final ConfigModel.GenAll.File file : genAll.getFile()) {
            if ("MultiFile".equals(file.getGenMode())) {
                for (final String tableName : tableNames) {
                    final TableModel tableModel = dbHelper.getByTable(tableName);
                    final Map<String, Object> map = new HashMap<String, Object>();
                    map.put("model", tableModel);
                    map.put("date", new Date());
                    this.genFile(file.getDir(), tableName + "." + file.getExtName(), file.getTemplate(), configModel.getCharset(), cfg, map);
                    Codegen.log.info(tableName + "." + file.getExtName() + " \u751f\u6210\u6210\u529f!");
                }
            }
            else {
                if (!"SingleFile".equals(file.getGenMode())) {
                    continue;
                }
                final List<TableModel> models = new ArrayList<TableModel>();
                for (final String tableName2 : tableNames) {
                    final TableModel tableModel2 = dbHelper.getByTable(tableName2);
                    models.add(tableModel2);
                }
                final Map<String, Object> map2 = new HashMap<String, Object>();
                map2.put("models", models);
                map2.put("date", new Date());
                this.genFile(file.getDir(), file.getFilename(), file.getTemplate(), configModel.getCharset(), cfg, map2);
                Codegen.log.info(file.getFilename() + " \u751f\u6210\u6210\u529f!");
            }
        }
        Codegen.log.info("----------------\u751f\u6210\u591a\u8868\u7ed3\u675f------------------");
    }
    
    private void genFile(final String fileDir, final String fileName, final String templatePath, final String charset, final Configuration cfg, final Map data) throws IOException, TemplateException {
        final String path = StringUtil.combilePath(fileDir, fileName);
        final File newFile = new File(fileDir, fileName);
        if (!newFile.exists()) {
            if (!newFile.getParentFile().exists()) {
                newFile.getParentFile().mkdirs();
            }
            newFile.createNewFile();
        }
        final Writer writer = new OutputStreamWriter(new FileOutputStream(newFile), charset);
        final Template template = cfg.getTemplate(templatePath, charset);
        template.process((Object)data, writer);
    }
    
    private void appendFile(final String fileDir, final String fileName, final String templatePath, final String charset, final Configuration cfg, final Map data, final String insertTag, final String startTag, final String endTag) throws IOException, TemplateException {
        final String path = StringUtil.combilePath(fileDir, fileName);
        final File newFile = new File(fileDir, fileName);
        final StringWriter out = new StringWriter();
        final Template template = cfg.getTemplate(templatePath, charset);
        template.process((Object)data, (Writer)out);
        String str = out.toString();
        boolean exists = false;
        String content = "";
        if (newFile.exists()) {
            content = FileHelper.readFile(path, charset);
            if (StringUtil.isNotEmpty(startTag) && StringUtil.isNotEmpty(endTag) && StringUtil.isExist(content, startTag, endTag)) {
                content = StringUtil.replace(content, startTag, endTag, str);
                exists = true;
            }
        }
        if (!exists) {
            if (StringUtil.isNotEmpty(startTag) && StringUtil.isNotEmpty(endTag)) {
                str = startTag.trim() + "\r\n" + str + "\r\n" + endTag.trim();
            }
            if (content.indexOf(insertTag) != -1) {
                final String[] aryContent = FileHelper.getBySplit(content, insertTag);
                content = aryContent[0] + str + "\r\n" + insertTag + aryContent[1];
            }
            else {
                content = content + "\r\n" + str;
            }
        }
        FileHelper.writeFile(newFile, charset, content);
    }
    
    private IDbHelper getDbHelper(final ConfigModel configModel) throws CodegenException {
        IDbHelper dbHelper = null;
        final String dbHelperClass = configModel.getDatabase().getDbHelperClass();
        try {
            dbHelper = (IDbHelper)Class.forName(dbHelperClass).newInstance();
        }
        catch (InstantiationException e) {
            throw new CodegenException("\u6307\u5b9a\u7684dbHelperClass\uff1a" + dbHelperClass + "\u65e0\u6cd5\u5b9e\u4f8b\u5316\uff0c\u53ef\u80fd\u8be5\u7c7b\u662f\u4e00\u4e2a\u62bd\u8c61\u7c7b\u3001\u63a5\u53e3\u3001\u6570\u7ec4\u7c7b\u3001\u57fa\u7840\u7c7b\u578b\u6216 void, \u6216\u8005\u8be5\u7c7b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u65b9\u6cd5!", e);
        }
        catch (IllegalAccessException e2) {
            throw new CodegenException("\u6307\u5b9a\u7684dbHelperClass" + dbHelperClass + "\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u65b9\u6cd5\u6216\u4e0d\u53ef\u8bbf\u95ee!", e2);
        }
        catch (ClassNotFoundException e3) {
            throw new CodegenException("\u627e\u4e0d\u5230\u6307\u5b9a\u7684dbHelperClass:" + dbHelperClass + "!", e3);
        }
        dbHelper.setUrl(configModel.getDatabase().getUrl(), configModel.getDatabase().getUsername(), configModel.getDatabase().getPassword());
        return dbHelper;
    }
    
    public IDbHelper getDbHelper(final String dbHelperClass, final String url, final String userName, final String passWord) throws CodegenException {
        IDbHelper dbHelper = null;
        try {
            dbHelper = (IDbHelper)Class.forName(dbHelperClass).newInstance();
        }
        catch (InstantiationException e) {
            throw new CodegenException("\u6307\u5b9a\u7684dbHelperClass\uff1a" + dbHelperClass + "\u65e0\u6cd5\u5b9e\u4f8b\u5316\uff0c\u53ef\u80fd\u8be5\u7c7b\u662f\u4e00\u4e2a\u62bd\u8c61\u7c7b\u3001\u63a5\u53e3\u3001\u6570\u7ec4\u7c7b\u3001\u57fa\u7840\u7c7b\u578b\u6216 void, \u6216\u8005\u8be5\u7c7b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u65b9\u6cd5!", e);
        }
        catch (IllegalAccessException e2) {
            throw new CodegenException("\u6307\u5b9a\u7684dbHelperClass" + dbHelperClass + "\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u65b9\u6cd5\u6216\u4e0d\u53ef\u8bbf\u95ee!", e2);
        }
        catch (ClassNotFoundException e3) {
            throw new CodegenException("\u627e\u4e0d\u5230\u6307\u5b9a\u7684dbHelperClass:" + dbHelperClass + "!", e3);
        }
        dbHelper.setUrl(url, userName, passWord);
        return dbHelper;
    }
    
    public void execute(final String packagePath, final String module, final String developer, final DataSourceConfig dbConfig, final List<String> tableNameList) throws Exception {
        this.execute(null, packagePath, module, developer, dbConfig, tableNameList);
    }
    
    public void execute(final String subProjectDir, final String packagePath, final String module, final String developer, final DataSourceConfig dbConfig, final List<String> tableNameList) throws Exception {
        try {
            String baseDir = System.getProperty("user.dir");
            if (!StringUtil.isEmpty(subProjectDir)) {
                baseDir = baseDir + File.separator + subProjectDir;
            }
            String dir = null;
            final String jarWholePath = Codegen.class.getProtectionDomain().getCodeSource().getLocation().getFile();
            try {
                dir = URLDecoder.decode(jarWholePath, "UTF-8");
            }
            catch (UnsupportedEncodingException e) {
                Codegen.log.error("UnsupportedEncodingException", (Throwable)e);
            }
            final String templateRootDir = dir;
            setRootPath(templateRootDir);
            final String configXml = "/codegenconfig.xml";
            final String style = "style1";
            final InputStream is = this.getClass().getResourceAsStream("/" + style + "/codegenconfig.xml");
            if (is == null) {
                throw new CodegenException("\u8bf7\u786e\u8ba4\u914d\u7f6e\u6587\u4ef6\uff1a" + configXml + "\u662f\u5426\u5b58\u5728!");
            }
            final String projectPath = System.getProperty("user.dir");
            final ConfigModel configModel = this.loadXml(style, baseDir);
            configModel.getVariables().put("parentDir", packagePath);
            final String xmlParentDir = packagePath.replace(".", "/");
            configModel.getVariables().put("xmlParentDir", xmlParentDir);
            configModel.getVariables().put("module", module);
            configModel.getVariables().put("developer", developer);
            configModel.setCharset("utf-8");
            final String url = dbConfig.getUrl();
            final ConfigModel configModel2 = configModel;
            final ConfigModel this$0 = configModel;
            this$0.getClass();
            configModel2.setDatabase(this$0.new Database(dbConfig.getDbType(), url, dbConfig.getUsername(), dbConfig.getPassword()));
            final List<ConfigModel.Table> tables = new ArrayList<ConfigModel.Table>();
            for (final String tableName : tableNameList) {
                final ConfigModel this$2 = configModel;
                this$2.getClass();
                final ConfigModel.Table table = this$2.new Table(tableName);
                table.setVariable(configModel.getVariables());
                tables.add(table);
            }
            configModel.setTables(tables);
            final Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
            cfg.setClassForTemplateLoading((Class)this.getClass(), "/" + style + "/template");
            final IDbHelper dbHelper = this.getDbHelper(configModel);
            this.genTableByConfig(dbHelper, configModel, cfg);
        }
        catch (Exception ex) {
            Codegen.log.error("execute\u5f02\u5e38", (Throwable)ex);
        }
    }
    
    static {
        log = LoggerFactory.getLogger((Class)Codegen.class);
    }
}
